package com.rtp2p.rtcoresdkdemo.play

import android.Manifest
import android.app.Application
import android.content.Context
import android.graphics.Bitmap
import android.icu.util.TimeZone
import android.view.MotionEvent
import android.view.View
import android.widget.Toast
import androidx.annotation.RequiresPermission
import androidx.lifecycle.MutableLiveData
import com.rtp2p.rtcoresdkdemo.base.BaseViewModel
import com.rtp2p.rtnetworkcamera.baseCamera.CameraNetStatus
import com.rtp2p.rtnetworkcamera.media.record.RTMP4Record
import com.rtp2p.rtnetworkcamera.media.render.RTVideoView
import com.rtp2p.rtp2pcore.core.AlarmParamRequest
import com.rtp2p.rtp2pcore.core.DeviceFacade
import com.rtp2p.rtp2pcore.core.LiveMediaSource
import com.rtp2p.rtp2pcore.core.MediaRender
import com.rtp2p.rtp2pcore.core.PtzRequest
import com.rtp2p.rtp2pcore.core.TFCardRecordParamRequest
import com.rtp2p.rtp2pcore.core.TFCardParamRequest
import com.rtp2p.rtp2pcore.core.TimeRequest
import com.rtp2p.rtp2pcore.core.WiFiRequest
import com.rtp2p.rtp2pcore.core.WorkmodeRequest
import com.rtp2p.rtp2pcore.core.CacheSnapRequest
import com.rtp2p.rtp2pcore.core.LedRequest
import com.rtp2p.rtp2pcore.core.TalkRequest
import com.rtp2p.rtp2pcore.core.WledRequest
import com.rtp2p.rtp2pcore.utils.RTFileUtils
import com.rtp2p.rtp2pcore.utils.RTLogUtils
import com.rtp2p.rtp2pcore.utils.RTTimeUtils
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import kotlin.code

class LiveViewModel(application: Application) : BaseViewModel(application) {
    private var online = false
    private var resolutionInfos: List<LiveMediaSource.Resolution> = emptyList()
    val adapter = MsgAdapter()

    //true:横屏
    val fullscreen: MutableLiveData<Boolean> = MutableLiveData<Boolean>().apply { value = false }
    private var workMode = WorkmodeRequest.WorkMode.LOWPOWER

    private var device: DeviceFacade? = null
    private var mediaSource: LiveMediaSource? = null
    private var mediaRender: MediaRender? = null
    private var ptzRequest: PtzRequest? = null
    private var talkRequest: TalkRequest? = null
    private var workmodeRequest: WorkmodeRequest? = null
    private var timeRequest: TimeRequest? = null
    private var wiFiRequest: WiFiRequest? = null
    private var alarmRequest: AlarmParamRequest? = null
    private var tfCardParamRequest: TFCardParamRequest? = null
    private var tfCardRecordParamRequest: TFCardRecordParamRequest? = null
    private var cacheSnapRequest: CacheSnapRequest? = null
    private var ledRequest: LedRequest? = null
    private var wledRequest: WledRequest? = null
    fun init(context: Context, deviceId: String, isAP: Boolean, videoView: RTVideoView) {
        device = DeviceFacade(deviceId, isAP)

        mediaSource = LiveMediaSource(device!!)
        mediaRender = MediaRender(context, videoView, mediaSource!!)
        ptzRequest = PtzRequest(device!!)
        talkRequest = TalkRequest(device!!) {
            if (it.success) isTalk = it.data
        }
        workmodeRequest = WorkmodeRequest(device!!)
        timeRequest = TimeRequest(device!!)
        alarmRequest = AlarmParamRequest(device!!)
        tfCardParamRequest = TFCardParamRequest(device!!)
        tfCardRecordParamRequest = TFCardRecordParamRequest(device!!)
        cacheSnapRequest = CacheSnapRequest(device!!)
        ledRequest = LedRequest(device!!)
        wledRequest = WledRequest(device!!)
        wiFiRequest = WiFiRequest(device!!){
            if (it.success) {
                var ssids = ""
                it.data.forEach {
                    ssids = "$ssids \n ${it.ssid}"
                }
                RTLogUtils.d(" $ssids")
                adapter.add("搜索wifi data:$ssids")
            } else {
                adapter.add("搜索wifi 失败 code:${it.code} msg:${it.message}")
            }
        }

        device?.setConnectStateListener {
            RTLogUtils.d("连接状态 state :${it.toString()}")
            online = DeviceFacade.Status.Connected == it
            if (online) {
                play()
                queryResolution()
                currentWorkMode()
            }
        }
    }

    internal fun onStart() {
        if (online)
            play()
        else
            connect()
    }

    internal fun onStop() {
        pause()
    }

    private fun connect() {
        device?.connect()
    }

    private fun disconnect() {
        device?.disconnect()
    }

    //开始播放
    private fun play() {
        mediaRender?.play()
        mediaSource?.play()
    }

    //停止播放
    private fun pause() {
        mediaSource?.pause()
        mediaRender?.pause()
    }

    //获取设备支持的分辨率
    private fun queryResolution() {
        mediaSource?.queryResolution {
            if (it.success) {
                RTLogUtils.d("resolutionInfos data:${it.data}")
                resolutionInfos = it.data
            } else {
                RTLogUtils.d("resolutionInfos code:${it.code} message:${it.message}")
            }
        }
    }

    //切换分辨率
    fun switchResolution() {
        var resolution = mediaSource?.resolution ?: return
        if(resolutionInfos.isEmpty())return

        if (resolutionInfos.size == 2) {
            if (resolution == resolutionInfos[0]) {
                resolution = resolutionInfos[1]
            } else {
                resolution = resolutionInfos[0]
            }
        }

        mediaSource?.switchResolution(resolution)
    }

    private var isTalk = false;

    //对讲
    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    fun btnTalk(context: Context) {
        if (!isTalk)
            talkRequest?.startTalk()
        else
            talkRequest?.stopTalk()
    }

    //获取工作模式
    private fun currentWorkMode() {
        workmodeRequest?.current() {
            if (it.success) {
                workMode = it.data
                this.adapter.add(if (WorkmodeRequest.WorkMode.NORMAL == workMode) "常电模式" else "低功耗")
            } else {
                RTLogUtils.e("获取工作模式 code:${it.code} msg:${it.message}")
            }
        }
    }

    //设置工作模式
    fun updateWorkMode() {
        workMode = if (WorkmodeRequest.WorkMode.LOWPOWER == workMode)
            WorkmodeRequest.WorkMode.NORMAL
        else
            WorkmodeRequest.WorkMode.LOWPOWER

        workmodeRequest?.update(workMode) {
            if (it.success) {
                currentWorkMode()
            } else {
                RTLogUtils.e("设置工作模式 code:${it.code} msg:${it.message}")
            }
        }
    }

    //设置时区
    fun updateTimezone(context: Context) {
        adapter.add("设置时区 开始")
        timeRequest?.updateTime(
            TimeRequest.DateTime(
                TimeZone.getDefault().getRawOffset() / 1000
            )
        ) {
            if (it.success) {
                Toast.makeText(context, "设置时区成功", Toast.LENGTH_SHORT).show()
                this.adapter.add("设置时区成功")
            } else {
                RTLogUtils.e("设置时区 code:${it.code} msg:${it.message}")
            }
        }
    }

    //时间戳设置 单位S
    fun updateTime(context: Context) {
        adapter.add("时间戳设置 开始")
        timeRequest?.syncTime(System.currentTimeMillis() / 1000) {
            if (it.success) {
                Toast.makeText(context, "时间戳设置成功", Toast.LENGTH_SHORT).show()
                this.adapter.add("时间戳设置 成功")
            } else {
                RTLogUtils.e("时间戳设置 code:${it.code} msg:${it.message}")
            }
        }
    }

    //重启
    fun reboot(context: Context) {
        adapter.add("重启 开始")
        device?.reboot() {
            if (it.success) {
                Toast.makeText(context, "重启 成功", Toast.LENGTH_SHORT).show()
            } else {
                RTLogUtils.e("重启 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //恢复出厂设置
    fun reset(context: Context) {
        adapter.add("恢复出厂设置 开始")
        device?.reset() {
            if (it.success) {
                Toast.makeText(context, "恢复出厂设置 成功", Toast.LENGTH_SHORT).show()
            } else {
                RTLogUtils.e("恢复出厂设置 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //声音开关
    fun btnOpenAudio() {
        val isOpenAudio = mediaRender?.isOpenAudio() ?: false
        if (!isOpenAudio) {
            mediaRender?.startOpenAudio()
        } else {
            mediaRender?.stopOpenAudio()
        }

        this.adapter.add(if (mediaRender?.isOpenAudio() == true) "打开音频" else "关闭音频")
    }

    //获取WiFi列表
    fun scanWifis(context: Context) {
        adapter.add("获取WiFi列表 开始")
        wiFiRequest?.scan()
    }

    //设置WiFi
    fun updateWifi(context: Context) {
        wiFiRequest?.update("rtxm_2.4G", "rt123456") {
            adapter.add("设置WiFi 开始")
            if (it.success) {
                adapter.add("设置WiFi 成功}")
            } else {
                adapter.add("设置WiFi 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    private var alarmEx: AlarmParamRequest.AlarmParam? = null

    //获取告警信息
    fun currentAlarm(context: Context) {
        adapter.add("获取告警信息 开始")
        alarmRequest?.current {
            if (it.success) {
                this.alarmEx = it.data
                adapter.add("获取告警信息 成功 ${this.alarmEx.toString()}")
            } else {
                adapter.add("获取告警信息 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //设置告警信息
    fun updateAlarm(context: Context) {
        adapter.add("设置告警信息 开始")
        alarmEx?.let {
            alarmRequest?.update(it) {
                if (it.success) {
                    adapter.add("设置告警信息 成功}")
                } else {
                    adapter.add("设置告警信息 失败 code:${it.code} msg:${it.message}")
                }
            }
        }
    }

    private var ledMode = LedRequest.LedMode.CLOSE

    //获取LEd
    fun currentLed(context: Context) {
        adapter.add("获取LEd 开始")
        ledRequest?.current() {
            if (it.success) {
                ledMode = it.data
                adapter.add("获取LEd 成功 ${ledMode.toString()}")
            } else {
                adapter.add("获取LEd 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //设置LEd
    fun updateLed(context: Context) {
        adapter.add("设置LEd 开始")
        ledRequest?.update(ledMode) {
            if (it.success) {
                adapter.add("设置LEd 成功}")
            } else {
                adapter.add("设置LEd 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //Wled
    private var wledMode = WledRequest.WledMode.CLOSE

    //获取Wled
    fun currentWled(context: Context) {
        adapter.add("获取Wled 开始")
        wledRequest?.current() {
            if (it.success) {
                wledMode = it.data
                adapter.add("获取Wled 成功 ${wledMode.toString()}")
            } else {
                adapter.add("获取Wled 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //设置Wled
    fun updateWled(context: Context) {
        adapter.add("设置Wled 开始")
        wledRequest?.update(wledMode) {
            if (it.success) {
                adapter.add("设置Wled 成功")
            } else {
                adapter.add("设置Wled 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    private var tfCardParamBean: TFCardParamRequest.TFCardParam? = null

    //获取TF卡容量等信息
    fun currentRecordInfo(context: Context) {
        adapter.add("获取TF卡容量等信息 开始")
        tfCardParamRequest?.current {
            if (it.success) {
                this.tfCardParamBean = it.data
                adapter.add("获取TF卡容量等信息 成功  ${this.tfCardParamBean.toString()}}")
                RTLogUtils.d("获取TF卡容量等信息 成功  ${this.tfCardParamBean.toString()}}")
            } else {
                adapter.add("获取TF卡容量等信息 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //格式化TF卡
    fun formatTFCard(context: Context) {
        adapter.add("格式化TF卡 开始")
        tfCardParamRequest?.format {
            if (it.success) {
                adapter.add("格式化TF卡 成功")
            } else {
                adapter.add("格式化TF卡 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    private var recordParam: TFCardRecordParamRequest.RecordParam? = null

    //获取录像参数
    fun currentSdRec(context: Context) {
        adapter.add("获取录像参数 开始")
        tfCardRecordParamRequest?.current {
            if (it.success) {
                this.recordParam = it.data
                adapter.add("获取录像参数 成功  ${this.recordParam.toString()}")
                RTLogUtils.d("获取录像参数 成功  ${recordParam.toString()}")
            } else {
                adapter.add("获取录像参数 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    //设置录像信息
    fun updateSdRec(context: Context) {
        adapter.add("设置录像信息 开始")
        recordParam?.let {
            tfCardRecordParamRequest?.update(it) {
                if (it.success) {
                    adapter.add("设置录像信息 成功")
                } else {
                    adapter.add("设置录像信息 失败 code:${it.code} msg:${it.message}")
                }
            }
        }
    }

    //缓存告警日志
    fun currentCacheSnap(context: Context) {
        adapter.add("缓存告警日志 开始")
        cacheSnapRequest?.current {
            if (it.success) {
                adapter.add("缓存告警日志 成功")
            } else {
                adapter.add("缓存告警日志 失败 code:${it.code} msg:${it.message}")
            }
        }
    }

    /************************************************/
    //拍照
    fun btnTakePictures(context: Context) {
        mediaRender?.onTakePictures {
            if (it.success) {
                try {
                    val deviceId = device?.deviceId?:return@onTakePictures
                    val path = RTFileUtils.currentFilePath(context, deviceId)
                    val name = RTTimeUtils.getPTZByFileName(System.currentTimeMillis())

                    val onSnapFile = File(path, "$name.jpg")
                    if (onSnapFile.exists()) onSnapFile.delete()

                    val fos = FileOutputStream(onSnapFile)
                    it.data.compress(Bitmap.CompressFormat.JPEG, 100, fos)
                    fos.close()

                    RTLogUtils.d("拍照成功 ${onSnapFile.absolutePath}")
                    Toast.makeText(
                        context,
                        "拍照成功 ${onSnapFile.absolutePath}",
                        Toast.LENGTH_SHORT
                    ).show()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
    }

    /************************************************/
    //录像
    fun btnRecord(context: Context) {
        val isRecord = mediaRender?.isRecord() ?: false
        if (!isRecord) {
            val deviceId = device?.deviceId?:return
            val path = RTFileUtils.currentFilePath(context, deviceId)?.absolutePath?:return
            val name = "${RTTimeUtils.getPTZByFileName(System.currentTimeMillis())}.mp4"
            mediaRender?.startRecord(path, name, object : RTMP4Record.RecordListener {
                override fun onTime(time: Long) {
                    RTLogUtils.d("录像时间： $time")
                }

                override fun onStart() {
                    RTLogUtils.d("开始录像")
                    adapter.add("开始录像")
                }

                override fun onComplete(result: Boolean) {
                    RTLogUtils.d("结束录像 $result")
                    adapter.add("结束录像")
                }
            })
        } else {
            mediaRender?.stopRecord()
        }
    }

    /************************************************/
    fun btnPtzUp(view: View, event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                ptzRequest?.move(PtzRequest.Direction.UP) {

                }
            }

            MotionEvent.ACTION_UP -> {
                ptzRequest?.move(PtzRequest.Direction.STOP) {

                }
            }
        }
        return true
    }

    fun btnPtzDown(view: View, event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                ptzRequest?.move(PtzRequest.Direction.DOWN) {

                }
            }

            MotionEvent.ACTION_UP -> {
                ptzRequest?.move(PtzRequest.Direction.STOP) {

                }
            }
        }
        return true
    }

    fun btnPtzLeft(view: View, event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                ptzRequest?.move(PtzRequest.Direction.LEFT) {

                }
            }

            MotionEvent.ACTION_UP -> {
                ptzRequest?.move(PtzRequest.Direction.STOP) {

                }
            }
        }
        return true
    }

    fun btnPtzRight(view: View, event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                ptzRequest?.move(PtzRequest.Direction.RIGHT) {

                }
            }

            MotionEvent.ACTION_UP -> {
                ptzRequest?.move(PtzRequest.Direction.STOP) {

                }
            }
        }
        return true
    }
}